package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyMontoPeriodoRequest;
import com.sisgesbyte.dao.proyeccion.MantProyeccionPeriodoDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionProductoPeriodoDao;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionPeriodoEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionProductoPeriodoEntity;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroProductoZonaBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionPeriodoResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionZonaResponse;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionPeriodoBean;
import com.sisgesbyte.services.proyeccion.bean.ZonaProyeccionBean;

@Stateless
public class MantProyeccionMontoPeriodoServiceImpl implements
		MantProyeccionMontoPeriodoService {

	@EJB
	private MantProyeccionPeriodoDao mantProyeccionPeriodoDao;
	@EJB
	private MantProyeccionZonaService mantProyeccionZonaService;
	@EJB
	private MantProyeccionProductoPeriodoDao mantProyeccionProductoPeriodoDao;
	@Inject
	private Validaciones validaciones;
	
	@Override
	public ListaProyeccionPeriodoResponse listaProyeccionMontoPeriodos(String codTransaccion) {
		String mensajeTransaccionMetodo = "[mostrarProyeccionGeneral idTx="
				+ codTransaccion + "] - ";
		ListaProyeccionPeriodoResponse response = new ListaProyeccionPeriodoResponse();

		List<ProyeccionPeriodoEntity>  responseDao =null;
		try{
			responseDao = mantProyeccionPeriodoDao.listaProyeccionPorPeriodo(null);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		if(responseDao.size() > 0){
			List<ProyeccionPeriodoBean> lista = new ArrayList<ProyeccionPeriodoBean>();
			for(ProyeccionPeriodoEntity ls :responseDao){
				ProyeccionPeriodoBean bean = new ProyeccionPeriodoBean();
				bean.setId(ls.getId());
				bean.setIdPeriodo(ls.getPeriodo_id());
				bean.setPeriodo(validaciones.validarCamposString(ls.getPeriodo()));
				bean.setMontoProyectado(ls.getMonto_proyectado());
				bean.setCodigoBanda(validaciones.validarCamposString(ls.getCodigo_banda()));
				
				BigDecimal totalZona=null;
				try{
					//capturamos el monto de proyeccion de las zonas 
					FiltroProductoZonaBean filtrosSQL = new FiltroProductoZonaBean();
					filtrosSQL.setIdPeriodo(ls.getPeriodo_id());
					filtrosSQL.setIdZona(0);
					ListaProyeccionZonaResponse listaZonas = mantProyeccionZonaService.listaProyeccionZonas(codTransaccion, filtrosSQL);
					totalZona = BigDecimal.ZERO;
					if(listaZonas.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						for(ZonaProyeccionBean zonas : listaZonas.getListaProyeccionZona()){
							totalZona = totalZona.add(zonas.getMontoPeriodo());
						}
					}
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo +"Error al obtener la lista de monto de las zonas " + e);
					totalZona = BigDecimal.ZERO;
				}
				bean.setMontoAsignado(totalZona);
				
			    int val = ls.getMonto_proyectado().compareTo(totalZona);
			    if( val == 0 ){
			    	bean.setEstadoAsignado(ConstProyeccion.COLOR_VERDE);
			    }else if( val == 1 ){
			    	bean.setEstadoAsignado(ConstProyeccion.COLOR_ROJO);
			    }
			    else if( val == -1 ){
			    	bean.setEstadoAsignado(ConstProyeccion.COLOR_AMARILLO);
			    };
			    
				lista.add(bean);
			}
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionPeriodo(lista);
		} else {
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}
		
		return response;
	}

	@Override
	public GenericResponse nuevaProyeccionMontoPeriodo(String codTransaccion,
			ProyeccionPeriodoBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccionMontoPeriodo idTx="
				+ codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try {
			ProyMontoPeriodoRequest req = new ProyMontoPeriodoRequest();
			req.setIdPeriodo(request.getIdPeriodo());
			req.setMontoProyectado(request.getMontoProyectado());
			responseDao = mantProyeccionPeriodoDao.guardarProyeccionMontoPeriodo(req);

			if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse editarProyeccionMontoPeriodo(String codTransaccion,
			ProyeccionPeriodoBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionMontoPeriodo idTx="+ codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try {
			ProyMontoPeriodoRequest req = new ProyMontoPeriodoRequest();
			req.setId(request.getId());
			req.setIdPeriodo(request.getIdPeriodo());
			req.setMontoProyectado(request.getMontoProyectado());
			responseDao = mantProyeccionPeriodoDao.actualizarProyeccionMontoPeriodo(req);

			if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al actualizar la Proyeccion del Monto del periodo en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse editarBandaProyeccionMontoPeriodo(
			String codTransaccion, ProyeccionPeriodoBean request) {
		String mensajeTransaccionMetodo = "[editarBandaProyeccionMontoPeriodo idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		GenericEntity responseDao = null;
		try {
			ProyMontoPeriodoRequest req = new ProyMontoPeriodoRequest();
			System.out.println("Id: " + request.getId());
			System.out.println("Periodo: " + request.getCodigoBanda());
			req.setId(request.getId());
			req.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
			
			responseDao = mantProyeccionPeriodoDao.actualizarBandaProyeccionMontoPeriodo(req);

			if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al actualizar la Banda de la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionMontoPeriodo(String codTransaccion,
			int codProyeccion) {
		String mensajeTransaccionMetodo = "[deleteProyeccionMontoPeriodo idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try {
			responseDao = mantProyeccionPeriodoDao.eliminarProyeccionMontoPeriodo(codProyeccion);
			if (responseDao.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)) {
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al eliminar  en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_EDITAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_EDITAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse actualizarMontoProyeccionPeriodo( String codTransaccion, int idPeriodo) {
		
		String mensajeTransaccionMetodo = "[editarBandaProyeccionMontoPeriodo idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();

		List<ProyeccionProductoPeriodoEntity> listaProyeccionPeriodos = null;
		
		FiltrosSQLBean cadenaFiltros = new FiltrosSQLBean();
		try{
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			FiltrosBean listaPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("ppp.periodo_id");
			listaPeriodo.setCampos(campoPeriodo);
			listaPeriodo.setOperador("=");
			filtro.add(listaPeriodo);
			valores.add(idPeriodo);
			cadenaFiltros.setListaFiltros(filtro);
			cadenaFiltros.setListaValores(valores);
			//1.- capturamos la lista de proyecciones del periodo
			listaProyeccionPeriodos = mantProyeccionProductoPeriodoDao.listaProyeccionProductoPeriodo(cadenaFiltros);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		//variable para verificar si se va actualizar o agregar el monto del periodo
		boolean update = false;	
		try{
			//2.-obtenemos la lista de montos de cada periodo
			ListaProyeccionPeriodoResponse listaMontosPeriodo = listaProyeccionMontoPeriodos(codTransaccion);
			
			if(listaMontosPeriodo.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				//3.- verificamos si el periodo ya existe registrado y proceder segun a actualizar o registrar
				
				for(ProyeccionPeriodoBean ls :listaMontosPeriodo.getListaProyeccionPeriodo() ){
					if(ls.getIdPeriodo()==idPeriodo){
						update=true;
						break;
					}
				}
			}else{
				System.out.println(mensajeTransaccionMetodo+ "Hubo un error funcional de Montos de cada Periodo de BD " );
				response.setCodigoRespuesta(listaMontosPeriodo.getCodigoRespuesta());
				response.setMensajeRespuesta(listaMontosPeriodo.getMensajeRespuesta());
				return response;
			}
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar de Montos de cada Periodo de BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		//4.- capturamos el monto del periodo
		
		BigDecimal montoTotalPeriodo = BigDecimal.ZERO;
		for(ProyeccionProductoPeriodoEntity listaProd : listaProyeccionPeriodos){
			if(listaProd.getPeriodo_id()==idPeriodo){
				montoTotalPeriodo = montoTotalPeriodo.add(listaProd.getPrecio_promedio().multiply(listaProd.getCantidad_proyectada()));
			}
		}
		
		ProyeccionPeriodoBean req = new ProyeccionPeriodoBean();
		req.setIdPeriodo(idPeriodo);
		req.setMontoProyectado(montoTotalPeriodo);
		if(update){
			try{
				GenericResponse editarProy = editarProyeccionMontoPeriodo(codTransaccion,  req);
				if(editarProy.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(editarProy.getCodigoRespuesta());
					response.setMensajeRespuesta(editarProy.getMensajeRespuesta());
				}
				
			}catch(Exception e){
				System.out.println("Error al tratar de Editar monto de proyeccion por periodo  "+ e);
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
				return response;
			}
		}else{
			try{
				GenericResponse nuevoProy = nuevaProyeccionMontoPeriodo(codTransaccion,  req);
				if(nuevoProy.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(nuevoProy.getCodigoRespuesta());
					response.setMensajeRespuesta(nuevoProy.getMensajeRespuesta());
				}
				
			}catch(Exception e){
				System.out.println("Error al tratar de Agregar el monto de proyeccion por periodo  "+ e);
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
				return response;
			}
		}
		return response;
	}
}
